package com.tencreat.service.mall.impl;

import cn.hutool.core.date.DateUtil;
import cn.hutool.core.date.LocalDateTimeUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.lock.annotation.Lock4j;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.conditions.query.LambdaQueryChainWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tencreat.common.constant.Lock4jConstant;
import com.tencreat.common.constant.MallConstants;
import com.tencreat.common.core.HttpResult;
import com.tencreat.common.core.domain.BaseEntity;
import com.tencreat.common.core.domain.OrderVO;
import com.tencreat.common.core.domain.entity.SysUser;
import com.tencreat.common.core.domain.model.IdAndPage;
import com.tencreat.common.core.domain.model.LoginUser;
import com.tencreat.common.core.domain.model.ReqIdParam;
import com.tencreat.common.core.domain.model.ReqIdsParam;
import com.tencreat.common.enums.*;
import com.tencreat.common.enums.mall.AllEnum;
import com.tencreat.common.exception.CustomException;
import com.tencreat.common.utils.DateUtils;
import com.tencreat.common.utils.LogisticsUtils;
import com.tencreat.common.utils.RabbitSendUtils;
import com.tencreat.common.utils.TenCreatUtil;
import com.tencreat.domain.account.MallUser;
import com.tencreat.domain.mall.*;
import com.tencreat.domain.mall.dto.*;
import com.tencreat.domain.mall.vo.*;
import com.tencreat.mapper.mall.MallOrderMapper;
import com.tencreat.mapper.mall.MallStoreOrderMapper;
import com.tencreat.service.account.IMallUserService;
import com.tencreat.service.mall.*;
import com.tencreat.service.system.ISysUserService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.text.ParseException;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 店铺订单Service业务层处理
 *
 * @author tencreat
 * @date 2021-08-13
 */
@Service
@Slf4j
@RequiredArgsConstructor
public class MallStoreOrderServiceImpl extends ServiceImpl<MallStoreOrderMapper, MallStoreOrder> implements IMallStoreOrderService {


    private final IMallAddressService mallAddressService;
    //    private final IMallGoodsService mallGoodsService;
    private final IMallStoreGoodsService mallStoreGoodsService;
    private final IMallStoreOrderGoodsService mallStoreOrderGoodsService;
    //    private final IMallOrderGoodsService mallOrderGoodsService;
    private final IMallCouponUserService mallCouponUserService;
    private final IMallCouponService mallCouponService;
    private final IMallUserService mallUserService;
    private final IMallSetmealNormsService mallSetmealNormsService;
    private final IMallMessageInformService mallMessageInformService;
    private final RabbitSendUtils rabbitUtils;
    private final IBalanceChangeService balanceChangeService;

    @Override
    public MallStoreOrder selectMallOrderById(ReqIdParam id) {
        return baseMapper.selectById(id.getId());
    }

    @Override
    public List<MallStoreOrder> selectMallOrderList(MallStoreOrder mallOrder) {
        return baseMapper.selectList(Wrappers.query(mallOrder));
    }

    @Override
    public int insertMallOrder(MallStoreOrder mallOrder) {
        mallOrder.setCreateTime(LocalDateTime.now());
        return baseMapper.insert(mallOrder);
    }

    @Override
    public int updateMallOrder(MallStoreOrder mallOrder) {
        mallOrder.setUpdateTime(LocalDateTime.now());
        return baseMapper.updateById(mallOrder);
    }

    @Override
    public int deleteMallOrderByIds(ReqIdsParam ids) {
        return baseMapper.deleteBatchIds(ids.getId());
    }

    @Override
    public int deleteMallOrderById(ReqIdParam id) {
        return baseMapper.deleteById(id.getId());
    }

    @Override
    public HttpResult<IPage<ResStoreOrderGoodsVO>> orderList(IdAndPage idParam, LoginUser loginUser) {
        Long uuid = loginUser.getAccountLogin().getUuid();
        IPage<ResStoreOrderGoodsVO> resOrderGoodsIPage = new Page<>(idParam.getPageNum(), idParam.getPageSize());
        return HttpResult.ok(baseMapper.getOrderList(resOrderGoodsIPage, idParam.getId(), uuid));
    }

    @Override
    public HttpResult<ResOrderGoodsVO> orderInfo(ReqIdParam idParam, LoginUser loginUser) {
        ResOrderGoodsVO orderInfo = baseMapper.getOrderInfo(idParam, loginUser.getAccountLogin().getUuid());

        // 退货地址
        if (orderInfo.getAddressId() != null) {
            IMallDeliverAddressService mallDeliverAddressService = SpringUtil.getBean(IMallDeliverAddressService.class);
            MallDeliverAddress deliverAddress = mallDeliverAddressService.lambdaQuery().eq(MallDeliverAddress::getId, orderInfo.getAddressId())
                    .select(MallDeliverAddress::getName, MallDeliverAddress::getTel, MallDeliverAddress::getId).one();
            orderInfo.setRefundAddress(mallDeliverAddressService.refundAddress(orderInfo.getAddressId()));
            orderInfo.setRefundName(deliverAddress.getName());
            orderInfo.setRefundPhone(deliverAddress.getTel());
        }

        return HttpResult.ok(orderInfo);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public synchronized HttpResult<ResOrderMallSubmitVO> submit(OrderStoreMallSubmitDTO param, LoginUser loginUser) {
        //消息队列时长 分钟
        Long min = 30L;
        Long uuid = loginUser.getAccountLogin().getUuid();
        if (uuid == null) {
            throw new CustomException("uuid不能为空");
        }
        // 校验参数信息
        //checkData(param);

        //商品订单
        List<MallStoreOrderGoods> orderGoodsList = new ArrayList<>();
        //总金额
        BigDecimal priceSum = new BigDecimal("0.00");
        //实付金额
        BigDecimal payPriceSum = new BigDecimal("0.00");
        //邮费
        BigDecimal postageSum = new BigDecimal("0.00");
        //
        BigDecimal couponPrice = new BigDecimal("0.00");

        MallCoupon coupon = null;
        //订单编号
        String orderSn = TenCreatUtil.getOrderNo();
        //用户ID
        MallUser mallUser = mallUserService.lambdaQuery().eq(MallUser::getUuid, uuid).one();
        //商品增加销量
        List<MallStoreGoods> goodList = new ArrayList<>();
        //规格减库存
        List<MallSetmealNorms> goodsNormsList = new ArrayList<>();
        //订单
        MallStoreOrder mallOrder = new MallStoreOrder();
        mallOrder.setOrderSn(orderSn);

        if (param.getVoucherId() != null) {
            coupon = mallCouponService.getById(param.getVoucherId());
            couponPrice = coupon.getDiscount();
        }
        BigDecimal memberTotal = new BigDecimal("0.00");
        // 抵扣金额
        BigDecimal deductPrice = new BigDecimal("0.00");
        //快递地址
        MallAddress mallAddress = null;
        if (param.getAddressId() != null) {
            mallAddress = mallAddressService.getById(param.getAddressId());
            mallOrder.setConsignee(mallAddress.getName());
            mallOrder.setMobile(mallAddress.getTel());
            //mallOrder.setAddress(mallAddress.getProvinceName() + mallAddress.getCityName() + mallAddress.getCountyName()+ mallAddress.getAddressDetail());
            //mallOrder.setAddressId(mallAddress.getId());
        }
        // 积分汇率
        //BigDecimal integerDiscount = new BigDecimal(DictUtils.getDictValue("integral_rate_config", "rate_config"));

        int count = 1;
        for (ResOrderMallGoodsVO goodPo : param.getGoods()) {
            //增加订单商品表
            MallStoreOrderGoods item = new MallStoreOrderGoods();
            item.setOrderStatus(OrderStatus.PAY);
            BigDecimal age = new BigDecimal("0.00");
            BigDecimal price = new BigDecimal("0.00");
            BigDecimal payPrice = new BigDecimal("0.00");
            BigDecimal memberPrice = new BigDecimal("0.00");
            MallStoreGoods goods = mallStoreGoodsService.getById(goodPo.getGoodsId());
            MallSetmealNorms goodsNorms = mallSetmealNormsService.getById(goodPo.getGoodsSpecId());
            if (goodsNorms.getInventory() <= 0 || goodsNorms.getInventory() < goodPo.getGoodsNum()) {
                throw new CustomException("库存不足购买失败");
            }
            //增加销量 减少库存
            goods.setCommoditySales(goods.getCommoditySales() == null ? 1 : goods.getCommoditySales() + 1);
            goods.setInventory(goods.getInventory() - goodPo.getGoodsNum());
            goodsNorms.setInventory(goodsNorms.getInventory() - goodPo.getGoodsNum());
            //存放 等待一次性修改
            goodList.add(goods);
            goodsNormsList.add(goodsNorms);
            //普通 计算优惠卷
            if (param.getOrderType().compareTo(OrderType.SHOP) == 0) {
                //判断商品
                price = goodsNorms.getRetailPrice().multiply(new BigDecimal(goodPo.getGoodsNum()));
                payPrice = goodsNorms.getRetailPrice().multiply(new BigDecimal(goodPo.getGoodsNum()));
                //deductPrice = deductPrice.add(goodsNorms.getDeductPrice());
            }
            //优惠券
            BigDecimal multiply = new BigDecimal("0.00");
            if (null != param.getPriceTotal()) {
                multiply = couponPrice.multiply(payPrice.divide(param.getPriceTotal(), 3, BigDecimal.ROUND_HALF_UP));
            }
/*            if (mallAddress != null) {
                item.setConsignee(mallAddress.getName());
                item.setMobile(mallAddress.getTel());
                item.setAddress(mallAddress.getProvinceName() + mallAddress.getCityName() + mallAddress.getCountyName()
                        + mallAddress.getAddressDetail());
                item.setReceiptAddressId(mallAddress.getId());
            }*/
            item.setOrderSn(orderSn);
            item.setOrderGoodsSn(orderSn + "-" + count);
            item.setGoodsId(goodPo.getGoodsId());
            item.setNormsId(Long.valueOf(goodPo.getGoodsSpecId()));
            item.setGoodsName(goods.getName());
            item.setGoodsSn(goods.getGoodsSn());
            //item.setPostage(age);
            item.setPayPrice(payPrice.subtract(multiply));
            item.setPrice(price);
            item.setCouponPrice(multiply);
            item.setNumber(goodPo.getGoodsNum());
            //item.setPicUrl(goodsNorms.getPicUrl());
            item.setComment(0L);
            item.setDelFlag("0");
            item.setUuid(uuid);
            item.setOrderType(param.getOrderType());
            item.setUpdateTime(LocalDateTime.now());
            item.setCreateTime(LocalDateTime.now());
            //item.setMemberPrice(memberPrice);
            orderGoodsList.add(item);
            //费用汇总
            postageSum = postageSum.add(age);
            payPriceSum = payPriceSum.add(payPrice);
            priceSum = priceSum.add(price);
            // 数量+1
            count++;
        }
        mallOrder.setUuid(uuid);
        // 活动ID
        //mallOrder.setActivityId(Long.valueOf(param.getShopId()));
        mallOrder.setOrderSn(orderSn);
        mallOrder.setOrderType(param.getOrderType());
        mallOrder.setStatusShop(ShopOrderStatus.PAY);
        mallOrder.setOrderStatus(OrderStatus.PAY);
        mallOrder.setStatusUser(UserOrderStatus.WAIT_PAY);

//        BigDecimal decimal = payPriceSum.add(postageSum).subtract(couponPrice).subtract(mallOrder.getDeductPrice());*/
        BigDecimal decimal = payPriceSum.add(postageSum).subtract(couponPrice);
        if (decimal.doubleValue() <= 0) {
            throw new CustomException("支付金额需大于0");
        }
        //设置配送费
        //mallOrder.setFreightPrice(postageSum);
        //mallOrder.setGoodsId(param.getGoods().get(0).getGoodsId());
        mallOrder.setAftersaleStatus(0);
        mallOrder.setMessage(param.getRemark());
        mallOrder.setGoodsPrice(priceSum);
        //mallOrder.setGrouponPrice(new BigDecimal("0.00"));
        mallOrder.setDelFlag("0");
        mallOrder.setCreateTime(LocalDateTime.now());
        mallOrder.setUpdateTime(LocalDateTime.now());
        mallOrder.setMessage(param.getRemark());
        mallOrder.setActualPrice(decimal);
        mallOrder.setOrderPrice(priceSum);
        mallOrder.setCouponPrice(couponPrice);
        //mallOrder.setMemberPrice(memberTotal);
        mallOrder.setEndTime(LocalDateTime.now().plusMinutes(min));
        //优惠券使用
        if (coupon != null) {
            mallOrder.setCouponId(coupon.getId());
            mallCouponUserService.updateState(coupon.getId(), uuid, AllEnum.couponType.USED.getType());
        }

        //订单10分钟未支付 取消
        sendDelayMessageCancelOrder(new OrderVO(mallOrder.getOrderSn(), mallOrder.getOrderType()), min);

        save(mallOrder);
        mallStoreOrderGoodsService.saveBatch(orderGoodsList);
        mallStoreGoodsService.updateBatchById(goodList);
        mallSetmealNormsService.updateBatchById(goodsNormsList);
        return HttpResult.ok(new ResOrderMallSubmitVO(orderSn, decimal));
    }

        @Override
        @Transactional(rollbackFor = Exception.class)
        public synchronized HttpResult<ResOrderMallSubmitVO> submitMember(OrderStoreMallSubmitDTO param, LoginUser loginUser){
            //消息队列时长 分钟
            Long min = 30L;
//        Long uuid = loginUser.getAccountLogin() == null ? param.getAutoPtUuid() : loginUser.getAccountLogin().getUuid();
            Long uuid = loginUser.getAccountLogin().getUuid();
            if (uuid == null) {
                throw new CustomException("uuid不能为空");
            }
            //商品订单
            List<MallStoreOrderGoods> orderGoodsList = new ArrayList<>();
            //总金额
            BigDecimal priceSum = new BigDecimal("0.00");
            //实付金额
            BigDecimal payPriceSum = new BigDecimal("0.00");
            //订单编号
            String orderSn = TenCreatUtil.getOrderNo();
            //商品增加销量
            List<MallStoreGoods> goodList = new ArrayList<>();
            //规格减库存
            List<MallSetmealNorms> goodsNormsList = new ArrayList<>();
            //订单
            MallStoreOrder mallOrder = new MallStoreOrder();
            mallOrder.setOrderSn(orderSn);
            for (ResOrderMallGoodsVO goodPo : param.getGoods()) {
                //增加订单商品表
                MallStoreOrderGoods item = new MallStoreOrderGoods();
                item.setOrderStatus(OrderStatus.PAY);
                BigDecimal age = new BigDecimal("0.00");
                BigDecimal price = new BigDecimal("0.00");
                BigDecimal payPrice = new BigDecimal("0.00");
                BigDecimal memberPrice = new BigDecimal("0.00");
                MallStoreGoods goods = mallStoreGoodsService.getById(goodPo.getGoodsId());
                MallSetmealNorms goodsNorms = mallSetmealNormsService.getById(goodPo.getGoodsSpecId());
                if (goodsNorms.getInventory() <= 0 || goodsNorms.getInventory() < goodPo.getGoodsNum()) {
                    throw new CustomException("库存不足购买失败");
                }
                //增加销量 减少库存
                goods.setCommoditySales(goods.getCommoditySales() == null ? 1 : goods.getCommoditySales() + 1);
                goods.setInventory(goods.getInventory() - goodPo.getGoodsNum());
                goodsNorms.setInventory(goodsNorms.getInventory() - goodPo.getGoodsNum());
                //存放 等待一次性修改
                goodList.add(goods);
                goodsNormsList.add(goodsNorms);
                item.setOrderSn(orderSn);
                item.setOrderGoodsSn(orderSn + "-" + 1);
                item.setGoodsId(goodPo.getGoodsId());
                item.setNormsId(Long.valueOf(goodPo.getGoodsSpecId()));
                item.setGoodsName(goods.getName());
                item.setGoodsSn(goods.getGoodsSn());
               // item.setPostage(age);
                item.setPayPrice(payPrice.subtract(BigDecimal.ZERO));
                item.setPrice(price);
                item.setCouponPrice(BigDecimal.ZERO);
                item.setNumber(goodPo.getGoodsNum());
                //item.setPicUrl(goodsNorms.getPicUrl());
                item.setComment(0L);
                item.setDelFlag("0");
                item.setUuid(uuid);
                item.setOrderType(param.getOrderType());
                item.setUpdateTime(LocalDateTime.now());
                item.setCreateTime(LocalDateTime.now());
                // item.setMemberPrice(memberPrice);
                orderGoodsList.add(item);
                payPriceSum = payPriceSum.add(payPrice);
                priceSum = priceSum.add(price);
            }
            mallOrder.setUuid(uuid);
            mallOrder.setOrderSn(orderSn);
            mallOrder.setOrderType(param.getOrderType());
            mallOrder.setStatusShop(ShopOrderStatus.PAY);
            mallOrder.setOrderStatus(OrderStatus.PAY);
            mallOrder.setStatusUser(UserOrderStatus.WAIT_PAY);
            mallOrder.setAftersaleStatus(0);
            //mallOrder.setMessage(param.getRemark());
            mallOrder.setGoodsPrice(priceSum);
            mallOrder.setDelFlag("0");
            mallOrder.setCreateTime(LocalDateTime.now());
            mallOrder.setUpdateTime(LocalDateTime.now());
            //mallOrder.setMessage(param.getRemark());
            mallOrder.setActualPrice(payPriceSum);
            mallOrder.setOrderPrice(priceSum);
            mallOrder.setCouponPrice(BigDecimal.ZERO);
            mallOrder.setEndTime(LocalDateTime.now().plusMinutes(min));

            //订单10分钟未支付 取消
            sendDelayMessageCancelOrder(new OrderVO(mallOrder.getOrderSn(), mallOrder.getOrderType()), min);

            save(mallOrder);
            mallStoreOrderGoodsService.saveBatch(orderGoodsList);
            mallStoreGoodsService.updateBatchById(goodList);
            mallSetmealNormsService.updateBatchById(goodsNormsList);
            return HttpResult.ok(new ResOrderMallSubmitVO(orderSn, priceSum));
        }

        @Override
        public HttpResult<ResStoreOrderMallBudgetVO> budget (StoreOrderMallBudgetDTO orderMallBudgetVO, LoginUser loginUser){
            ResStoreOrderMallBudgetVO resOrderMallBudget = new ResStoreOrderMallBudgetVO();
            // 查询用户
            MallUser mallUser = mallUserService.lambdaQuery().eq(MallUser::getUuid, loginUser.getAccountLogin().getUuid()).one();
            if (mallUser == null || mallUser.getStatus() != 0) {
                throw new CustomException("用户信息有误");
            }
            List<ResStoreOrderMallBudgetGoodsVO> goods = new ArrayList<>();
            // 商品总价
            BigDecimal priceTotal = new BigDecimal("0.00");
            BigDecimal postAgeTotal = new BigDecimal("0.00");

            // 抵扣金额
            BigDecimal deductPrice = new BigDecimal("0.00");
            for (ResOrderMallGoodsVO good : orderMallBudgetVO.getGoods()) {
                MallStoreGoods mallGoods = mallStoreGoodsService.getOne(new QueryWrapper<MallStoreGoods>().eq("id", good.getGoodsId()));
                MallSetmealNorms mallGoodsNorms = mallSetmealNormsService.getOne(new QueryWrapper<MallSetmealNorms>().eq("id", good.getGoodsSpecId()).eq("goods_id", good.getGoodsId()));
                BigDecimal payPrice = null;
                if (OrderType.SHOP.getValue() == orderMallBudgetVO.getOrderType().getValue()) {
                    payPrice = mallGoodsNorms.getRetailPrice().multiply(new BigDecimal(good.getGoodsNum()));
                }
                //deductPrice = deductPrice.add(mallGoodsNorms.getDeductPrice());

                priceTotal = priceTotal.add(payPrice);
                //快递价
                BigDecimal postAgePrice = BigDecimal.ZERO;
/*                if (MallConstants.MALL_LOGISTICS_POST.longValue() == mallGoods.getLogisticsId().longValue() && orderMallBudgetVO.getAddressId() != null) {
                    postAgePrice = mallAddressService.getPostAgeByGood(good.getGoodsId(), orderMallBudgetVO.getAddressId());
                    postAgePrice = postAgePrice == null ? BigDecimal.ZERO : postAgePrice;
                    postAgeTotal = postAgeTotal.add(postAgePrice);
                }*/

                ResStoreOrderMallBudgetGoodsVO resOrderMallBudgetGoods = new ResStoreOrderMallBudgetGoodsVO();
                resOrderMallBudgetGoods.setGoodsId(good.getGoodsId().intValue());
                resOrderMallBudgetGoods.setGoodsNum(good.getGoodsNum());
                resOrderMallBudgetGoods.setProductId(good.getGoodsProductId());
                resOrderMallBudgetGoods.setGoodsSpecId(good.getGoodsSpecId());
                resOrderMallBudgetGoods.setGoodsName(mallGoods.getName());
                resOrderMallBudgetGoods.setGoodsImg(mallGoods.getPicUrl());
                resOrderMallBudgetGoods.setGoodsPrice(mallGoodsNorms.getRetailPrice().doubleValue());
                resOrderMallBudgetGoods.setGoodsPriceStr(mallGoodsNorms.getRetailPrice().toString());
                resOrderMallBudgetGoods.setPostagePrice(postAgePrice.doubleValue());
                MallSetmealNorms goodsNorms = mallSetmealNormsService.getById(good.getGoodsSpecId());
                resOrderMallBudgetGoods.setNorms(goodsNorms);
                goods.add(resOrderMallBudgetGoods);
            }

            //优惠券
            BigDecimal discount = new BigDecimal("0.00");
            if (orderMallBudgetVO.getVoucherId() != null) {
                MallCoupon coupon = SpringUtil.getBean(IMallCouponService.class).getById(orderMallBudgetVO.getVoucherId());
                discount = coupon.getDiscount();
            }
            if (priceTotal.compareTo(discount) < 0) {
                return HttpResult.error("优惠的金额不能大于商品总金额");
            }
            BigDecimal sum = priceTotal.add(postAgeTotal).subtract(discount);
            if (sum.doubleValue() <= 0) {
                throw new CustomException("支付金额需大于0");
            }
            resOrderMallBudget.setPricePay(sum);
            resOrderMallBudget.setPriceTotal(priceTotal);
            resOrderMallBudget.setDiscountVoucherPrice(discount);
            //resOrderMallBudget.setPricePostage(postAgeTotal);
            resOrderMallBudget.setGoods(goods);
            return HttpResult.ok(resOrderMallBudget);
        }

        @Override
        public ResCheckMoneyVO checkMoney (OrderMallSubmitDTO param, LoginUser loginUser){
            BigDecimal priceTotal = new BigDecimal("0.00");
            BigDecimal pricePay = new BigDecimal("0.00");
            BigDecimal freightPrice = new BigDecimal("0.00");

            if (!Optional.ofNullable(param.getVoucherId()).isPresent()) {
                MallCoupon mallCoupon = mallCouponService.getById(param.getVoucherId());
                pricePay = pricePay.subtract(mallCoupon.getDiscount());
                priceTotal = priceTotal.subtract(mallCoupon.getDiscount());
            }

            return new ResCheckMoneyVO(priceTotal, pricePay, freightPrice);
        }


        @Override
        public HttpResult<MallOrderStatisticsVO> getInfoNum (MallStoreOrder mallOrder){
            MallOrderStatisticsVO mallOrderStatisticsVO = new MallOrderStatisticsVO();
            // 所有订单收入
            BigDecimal totalRevenue = baseMapper.queryOrderPayPrice(null, mallOrder.getUserId(), mallOrder.getBeginTime(), mallOrder.getEndTime());
            // 今日订单收人
            BigDecimal todayRevenue = baseMapper.queryOrderPayPrice(LocalDateTime.now(), mallOrder.getUserId(), mallOrder.getBeginTime(), mallOrder.getEndTime());
            // 所有订单数目
            Integer totalCount = baseMapper.queryOrderCount(null, mallOrder.getUserId(), mallOrder.getBeginTime(), mallOrder.getEndTime());
            // 今日订单数目
            Integer todayCount = baseMapper.queryOrderCount(LocalDateTime.now(), mallOrder.getUserId(), mallOrder.getBeginTime(), mallOrder.getEndTime());


            mallOrderStatisticsVO.setTotalOrderRevenue(totalRevenue);
            mallOrderStatisticsVO.setTodayRevenue(todayRevenue);
            mallOrderStatisticsVO.setOrderNum(totalCount);
            mallOrderStatisticsVO.setTodayOrderNum(todayCount);
            mallOrderStatisticsVO.setOrderRevenue(totalRevenue);
            mallOrderStatisticsVO.setTodayOrderRevenue(todayRevenue);

            return HttpResult.ok(mallOrderStatisticsVO);
        }

        @Override
        public HttpResult<String> selectOrderNum (MallStoreOrder mallOrder) throws ParseException {
            Map<String, Object> param = mallOrder.getParams();
            param.put("StatusUser", UserOrderStatus.OK.getValue());
            mallOrder.setParams(param);
            List<DateAndDataVO> dateAndDataVOS = baseMapper.countNewOrderNum(mallOrder);
            // 将所有日期转成时间戳
            List<Object[]> result = new ArrayList<>(dateAndDataVOS.size());
            for (DateAndDataVO item : dateAndDataVOS) {

                result.add(new Object[]{DateUtils.dateTime("yyyy-MM-dd", DateUtils.dateTime(item.getDbDate())).getTime(),
                        item.getDbData()});
            }
            return HttpResult.ok(JSONObject.toJSONString(result));
        }

        @Override
        public HttpResult<MallStoreOrderVO> selectOrderDetailsById (ReqIdParam reqIdParam){
            MallStoreOrder mallOrder = lambdaQuery().eq(MallStoreOrder::getId, reqIdParam.getId()).one();
            MallUser mallUserServiceOne = mallUserService
                    .getOne(new QueryWrapper<MallUser>().eq("uuid", mallOrder.getUuid()));
            MallStoreOrderVO mallOrderVO = new MallStoreOrderVO();
            BeanUtils.copyProperties(mallOrderVO, mallOrder);
            BeanUtils.copyProperties(mallOrderVO, mallUserServiceOne);
            List<MallStoreOrderGoods> orderGoods = mallStoreOrderGoodsService.list(new QueryWrapper<MallStoreOrderGoods>().eq("order_sn", mallOrder.getOrderSn()));
            mallOrderVO.setGoods(orderGoods);
            mallOrderVO.setNumber(orderGoods.size());
            return HttpResult.ok(mallOrderVO);
        }


        @Override
        public HttpResult<MallOrderStatisticsVO> getInfo (MallStoreOrder mallStoreOrder){
            List<MallUser> list = mallUserService.list();
            Integer todayUserCount = mallUserService.lambdaQuery().apply("date_format(create_time,'%Y%m%d') = " + "'" + LocalDateTime.now() + "'").count();
            // 所有订单收入
            BigDecimal totalRevenue = baseMapper.queryOrderPayPrice(null, mallStoreOrder.getUserId(), null, null);
            // 今日订单收人
            BigDecimal todayRevenue = baseMapper.queryOrderPayPrice(LocalDateTime.now(), mallStoreOrder.getUserId(), null, null);
            // 所有订单数目
            Integer totalCount = baseMapper.queryOrderCount(null, mallStoreOrder.getUserId(), null, null);
            // 今日订单数目
            Integer todayCount = baseMapper.queryOrderCount(LocalDateTime.now(), mallStoreOrder.getUserId(), null, null);
            Integer count = 0;
            Integer todayGoodsCount = 0;
            Integer count1 = 0;
            Integer todayGoodsCount1 = 0;
            BigDecimal totalOut = BigDecimal.ZERO;
            BigDecimal todayOut = BigDecimal.ZERO;
            if (mallStoreOrder.getUserId() != null) {
                // 所有上架商品数量
                count = mallStoreGoodsService.lambdaQuery().eq(MallStoreGoods::getUserId, mallStoreOrder.getUserId())
                        // .eq(MallStoreGoods::getSupplier, 1)
                        .eq(MallStoreGoods::getIsOnSale, 1)
                        .eq(MallStoreGoods::getAuditStatus, 1)
                        .count();
                // 今日上架
                DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyyMMdd");
                todayGoodsCount = mallStoreGoodsService.lambdaQuery().eq(MallStoreGoods::getUserId, mallStoreOrder.getUserId())
                        //.eq(MallStoreGoods::getSupplier, 1)
                        .eq(MallStoreGoods::getIsOnSale, 1)
                        .eq(MallStoreGoods::getAuditStatus, 1)
                        .apply("date_format(create_time,'%Y%m%d') = " + "'" + dateTimeFormatter.format(LocalDateTime.now()) + "'")
                        .count();
                // 待通过数量
                count1 = mallStoreGoodsService.lambdaQuery().eq(MallStoreGoods::getUserId, mallStoreOrder.getUserId())
                        //.eq(MallStoreGoods::getSupplier, 1)
                        .eq(MallStoreGoods::getAuditStatus, 0)
                        .count();
                todayGoodsCount1 = mallStoreGoodsService.lambdaQuery().eq(MallStoreGoods::getUserId, mallStoreOrder.getUserId())
                        //.eq(MallStoreGoods::getSupplier, 1)
                        .eq(MallStoreGoods::getAuditStatus, 0)
                        .apply("date_format(create_time,'%Y%m%d') = " + "'" + dateTimeFormatter.format(LocalDateTime.now()) + "'")
                        .count();
                // 所有订单支出
                totalOut = baseMapper.queryOrderOut(null, mallStoreOrder.getUserId());
                // 今日订单支出
                todayOut = baseMapper.queryOrderOut(LocalDateTime.now(), mallStoreOrder.getUserId());
            }


            MallOrderStatisticsVO mallOrderStatisticsVO = new MallOrderStatisticsVO();
            mallOrderStatisticsVO.setOrderNum(totalCount != null ? totalCount : 0);
            mallOrderStatisticsVO.setTodayOrderNum(todayCount != null ? todayCount : 0);
            mallOrderStatisticsVO.setOrderRevenue(totalRevenue != null ? totalRevenue : BigDecimal.ZERO);
            mallOrderStatisticsVO.setTodayRevenue(todayRevenue != null ? todayRevenue : BigDecimal.ZERO);
            mallOrderStatisticsVO.setUserNum(list.size());
            mallOrderStatisticsVO.setTodayUserNum(todayUserCount);
            mallOrderStatisticsVO.setGoodsNum(count);
            mallOrderStatisticsVO.setTodayGoodsNum(todayGoodsCount);
            mallOrderStatisticsVO.setWaitGoodsNum(count1);
            mallOrderStatisticsVO.setWaitTodayGoodsNum(todayGoodsCount1);
            mallOrderStatisticsVO.setOrderOut(totalOut);
            mallOrderStatisticsVO.setTodayOut(todayOut);

            return HttpResult.ok(mallOrderStatisticsVO);
        }

        @Override
        public HttpResult<Boolean> confirmOrder (ReqIdParam idParam, LoginUser loginUser){
            MallStoreOrderGoods orderGoods = mallStoreOrderGoodsService.lambdaQuery().eq(MallStoreOrderGoods::getOrderSn, idParam.getId()).eq(MallStoreOrderGoods::getNormsId, idParam.getNormsId()).one();
            orderGoods.setOrderStatus(OrderStatus.DAI_CENTXT);
            orderGoods.setConfirmTime(LocalDateTime.now());
            mallMessageInformService.addOrderMessage("您的商品已收货成功", orderGoods.getId(), loginUser.getAccountLogin().getUuid());
            handleData(orderGoods);

            return HttpResult.ok(mallStoreOrderGoodsService.updateById(orderGoods));
        }

        /**
         * 处理货款及收益
         *
         * @param mallStoreOrderGoods
         */
        @Override
        public void handleData (MallStoreOrderGoods mallStoreOrderGoods){
            //供应商商品应将货款打入账户
            MallStoreGoods mallGoods = mallStoreGoodsService.getById(mallStoreOrderGoods.getGoodsId());
            if (mallGoods.getStore() == 1) {
                BalanceChange balanceChange = balanceChangeService.lambdaQuery()
                        .eq(BalanceChange::getSource, mallStoreOrderGoods.getOrderGoodsSn())
                        .eq(BalanceChange::getBusinessType, BalanceBusinessType.ORDER_ADD)
                        .eq(BalanceChange::getBalanceType, BalanceTypeEnum.FINANCE_WAIT)
                        .one();

                // 减少待结算货款
                rabbitUtils.sendBalanceMessage(balanceChange.getUuid(), balanceChange.getChangAmount().negate(), AllEnum.BalanceChangeTypeEnums.EXPENDITURE.getType(), BalanceBusinessType.ORDER_CONFIRM, "确认收货", balanceChange.getSource(), BalanceTypeEnum.FINANCE_WAIT);
                // 增加货款
                rabbitUtils.sendBalanceMessage(balanceChange.getUuid(), balanceChange.getChangAmount().abs(), AllEnum.BalanceChangeTypeEnums.INCOME.getType(), BalanceBusinessType.ORDER_CONFIRM, "确认收货", balanceChange.getSource(), BalanceTypeEnum.FINANCE);

            }
            // 增加累积收益减少待结算收益
            List<BalanceChange> list = balanceChangeService.lambdaQuery()
                    .eq(BalanceChange::getSource, mallStoreOrderGoods.getOrderGoodsSn())
                    .in(BalanceChange::getBusinessType, BalanceBusinessType.DIRECT_REFERRER, BalanceBusinessType.INDIRECT_REFERRER)
                    .eq(BalanceChange::getBalanceType, BalanceTypeEnum.WAIT_INCOME)
                    .list();
            for (BalanceChange balanceChange : list) {
                // 减少待结算收益
                rabbitUtils.sendBalanceMessage(balanceChange.getUuid(), balanceChange.getChangAmount().negate(), AllEnum.BalanceChangeTypeEnums.EXPENDITURE.getType(), BalanceBusinessType.ORDER_CONFIRM, "确认收货", balanceChange.getSource(), BalanceTypeEnum.WAIT_INCOME);
                // 增加收益
                rabbitUtils.sendBalanceMessage(balanceChange.getUuid(), balanceChange.getChangAmount().abs(), AllEnum.BalanceChangeTypeEnums.INCOME.getType(), balanceChange.getBusinessType(), "确认收货", balanceChange.getSource(), BalanceTypeEnum.INCOME);
                // 增加余额
                rabbitUtils.sendBalanceMessage(balanceChange.getUuid(), balanceChange.getChangAmount().abs(), AllEnum.BalanceChangeTypeEnums.INCOME.getType(), balanceChange.getBusinessType(), "确认收货", balanceChange.getSource(), BalanceTypeEnum.BALANCE);
            }
        }

        @Override
        public HttpResult<List<MallNewOrderVO>> selectNewOrders (MallStoreOrder mallStoreOrder){
            List<MallStoreOrder> mallOrders = baseMapper.selectOrderList(mallStoreOrder);
            List<MallNewOrderVO> mallNewOrders = new ArrayList<>();
            for (MallStoreOrder order : mallOrders) {
                MallNewOrderVO mallNewOrder = new MallNewOrderVO();
                MallUser mallUserServiceOne = mallUserService.getOne(new QueryWrapper<MallUser>().eq("uuid", order.getUuid()));
                mallNewOrder.setUsername(mallUserServiceOne == null ? "" : mallUserServiceOne.getUsername());
                mallNewOrder.setActualPrice(order.getActualPrice());
                mallNewOrder.setUuId(order.getUuid());
                mallNewOrder.setOrderSn(order.getOrderSn());
                mallNewOrder.setOrderType(order.getOrderType());
                mallNewOrder.setCreateTime(order.getCreateTime());
                mallNewOrders.add(mallNewOrder);
            }
            mallNewOrders.stream().sorted(Comparator.comparing(MallNewOrderVO::getCreateTime).reversed())
                    .collect(Collectors.toList());

            return HttpResult.ok(mallNewOrders);
        }


        @Override
        public Page<MallStoreOrder> page (IPage < MallStoreOrder > page, MallStoreOrder mallStoreOrder){
            if (mallStoreOrder.getOrderType() != null) {
                mallStoreOrder.setOrderTypeValue(mallStoreOrder.getOrderType().getValue());
            }
            Page<MallStoreOrder> page1 = baseMapper.page(page, mallStoreOrder);
            page1.getRecords().forEach(item -> {
                item.setOrderTypeDesc(item.getOrderType() != null ? item.getOrderType().getDesc() : "-");
                if (item.getAftersaleStatus() == AfterSaleStatus.BUYER_DEAL.getValue()
                        || item.getAftersaleStatus() == AfterSaleStatus.DEL_PAY.getValue()
                        || item.getAftersaleStatus() == AfterSaleStatus.WAIT_RECEIVED.getValue()
                        || item.getAftersaleStatus() == AfterSaleStatus.ALREADY_APPLIED.getValue()) {
                    item.setOrderStatusDesc("已售后");
                } else {
                    item.setOrderStatusDesc(item.getOrderStatus() != null ? item.getOrderStatus().getDesc() : "-");
                }
                item.setAftersaleStatusDesc(AfterSaleStatus.getName(item.getAftersaleStatus()));
                //item.setIntegralPrice(item.getIntegralPrice() != null ? item.getIntegralPrice() : BigDecimal.ZERO);
                if (null != item.getPayType()) {
                    item.setPayTypeDesc(item.getPayType().getDesc());
                } else {
                    item.setPayTypeDesc("-");
                }
            });
            return page1;
        }

        @Override
        public ResOrderDetailInfoVO getOrderDetail (ReqIdParam id){
            Long orderId = id.getId();

            ResOrderDetailInfoVO detail = new ResOrderDetailInfoVO();

            MallStoreOrder mallOrder = lambdaQuery().eq(MallStoreOrder::getId, orderId).one();

            LambdaQueryChainWrapper<MallStoreOrderGoods> wrapper = mallStoreOrderGoodsService.lambdaQuery();
            wrapper.eq(MallStoreOrderGoods::getOrderSn, mallOrder.getOrderSn());
            if (id.getGoodId() != null) {
                wrapper.eq(MallStoreOrderGoods::getId, id.getGoodId());
            }
            List<MallStoreOrderGoods> orderGoodList = wrapper.list();
            List<ResOrderDetailInfoVO.GoodsInfo> goodsInfos = new ArrayList<>();
            if (orderGoodList.size() < 1) {
                throw new CustomException("没有找到订单下的商品");
            }
            detail.setOrderDetail(ResOrderDetailInfoVO.OrderDetail.builder()
                    .orderSn(orderGoodList.get(0).getOrderGoodsSn() != null ? orderGoodList.get(0).getOrderGoodsSn() : mallOrder.getOrderSn())
                    .generateTime(mallOrder.getCreateTime())
                    .orderStatus(orderGoodList.get(0).getOrderStatus())
                    .payAmount(orderGoodList.get(0).getPayPrice())
                    .payType(mallOrder.getPayType() == null ? "" : mallOrder.getPayType().getDesc())
                    .afterSaleStatus(orderGoodList.get(0).getAftersaleStatus())
                    .remark(mallOrder.getMessage())
                    .createTime(mallOrder.getCreateTime())
                    .payTime(mallOrder.getPayTime())
                    .endTime(mallOrder.getEndTime())
                    .updateTime(orderGoodList.get(0).getUpdateTime())
                    .build());
            for (MallStoreOrderGoods orderGoods : orderGoodList) {
                MallStoreGoods goods = mallStoreGoodsService.lambdaQuery().eq(MallStoreGoods::getId, orderGoods.getGoodsId()).one();
                if (goods == null) {
                    throw new CustomException("订单下的商品找不到了");
                }
                String supplierPhone = "";
                String supplierName = "";
                if (MallConstants.MALL_TRUE.equals(goods.getStore())) {
                    SysUser sysUser = SpringUtil.getBean(ISysUserService.class).selectUserById(goods.getUserId());
                    supplierName = sysUser == null ? "" : sysUser.getUserName();
                    supplierPhone = sysUser == null ? "" : sysUser.getPhonenumber();
                }
                MallAppCategory mallCategory = SpringUtil.getBean(IMallAppCategoryService.class).lambdaQuery().eq(MallAppCategory::getId, goods.getCategoryId()).one();
                MallSetmealNorms mallGoodsNorms = mallSetmealNormsService.lambdaQuery().eq(MallSetmealNorms::getId, orderGoods.getNormsId()).select(MallSetmealNorms::getGoodsId,
                        MallSetmealNorms::getAttribute).one();
                ResOrderDetailInfoVO.GoodsInfo goodsInfo = ResOrderDetailInfoVO.GoodsInfo.builder()
                        .goodsId(orderGoods.getGoodsId())
                        .goodsName(orderGoods.getGoodsName())
                        .picUrl(orderGoods.getPicUrl())
                        .category(mallCategory == null ? "" : mallCategory.getName())
                        .orderType(mallOrder.getOrderType())
                        .goodsNum(orderGoods.getNumber())
                        .supplierPhone(supplierPhone)
                        .supplierName(supplierName)
                        //.memberPrice(orderGoods.getMemberPrice())
                        .actualPrice(orderGoods.getPayPrice())
                        .price(orderGoods.getPrice())
                        .couponPrice(orderGoods.getCouponPrice())
                        //.deductPrice(orderGoods.getDeductPrice())
                        .attribute(mallGoodsNorms.getAttribute())
                        //.supplyPrice(mallGoodsNorms.getSupplyPrice().multiply(new BigDecimal(orderGoods.getNumber())))
                        //.shipTime(orderGoods.getShipTime())
                        .confirmTime(orderGoods.getConfirmTime())
                        .build();
                goodsInfos.add(goodsInfo);
            }
            detail.setGoodsInfo(goodsInfos);
            MallUser user = mallUserService.lambdaQuery().eq(MallUser::getUuid, mallOrder.getUuid()).one();

            detail.setUserInfo(ResOrderDetailInfoVO.UserInfo.builder()
                    .uuid(mallOrder.getUuid())
                    .userPhone(user == null ? "" : user.getMobile())
                    //.address(orderGoodList.get(0).getAddress() != null ? orderGoodList.get(0).getAddress() : mallOrder.getAddress())
                    .consignee(orderGoodList.get(0).getConsignee() != null ? orderGoodList.get(0).getConsignee() : mallOrder.getConsignee())
                    .consigneePhone(orderGoodList.get(0).getMobile() != null ? orderGoodList.get(0).getMobile() : mallOrder.getMobile())
                    .build());

            MallAftersale aftersale = SpringUtil.getBean(IMallAftersaleService.class).lambdaQuery().eq(MallAftersale::getOrderId, orderId).eq(MallAftersale::getOrderGoodsId, id.getGoodId()).one();
            detail.setAftersaleInfo(ResOrderDetailInfoVO.AfterSaleInfo.builder()
                    .uuid(mallOrder.getUuid())
                    .userPhone(user == null ? "" : user.getMobile())
                    .describe(aftersale == null ? "" : aftersale.getReason())
                    .refundAmount(aftersale == null ? new BigDecimal(0) : aftersale.getAmount())
                    .images(aftersale == null || aftersale.getPictures() == null ? null : Arrays.asList(aftersale.getPictures().split(",")))
                    .createTime(aftersale == null ? null : aftersale.getCreateTime())
                    .endTime(aftersale == null ? null : aftersale.getEndTime())
                    .type(aftersale == null ? null : aftersale.getType())
                    .build());

/*            //快递
            if (StrUtil.isNotEmpty(orderGoodList.get(0).getShipSn())) {
                HttpResult<?> httpResult = LogisticsUtils.checkLogistics(orderGoodList.get(0).getShipSn());
                detail.setLogisticsInfo((JSONObject) httpResult.getData());
            } else {
                detail.setLogisticsInfo(null);
            }*/
            // 退货物流

            if (null != aftersale && StrUtil.isNotEmpty(aftersale.getShipSn())) {
                HttpResult<?> httpResult = LogisticsUtils.checkLogistics(aftersale.getShipSn());
                detail.setLogisticsInfo2((JSONObject) httpResult.getData());
            } else {
                detail.setLogisticsInfo2(null);
            }
            return detail;
        }

        @Override
        public HttpResult<List<Map<String, Object>>> getOrderNumDaily (MallUserAndOrderTimeDTO dto){
            List<Map<String, Object>> res = new ArrayList<>();
            if (dto.getBeginTime() == null || dto.getEndTime() == null) {
                LocalDateTime endOfDay = LocalDateTimeUtil.endOfDay(LocalDateTime.now());
                MallUser mallUser = mallUserService.lambdaQuery().orderByAsc(BaseEntity::getCreateTime).last("limit 1").one();
                String startTime = DateUtil.format(mallUser.getCreateTime(), "yyyy-MM-dd");
                String endTime = DateUtil.format(endOfDay, "yyyy-MM-dd");
                dto.setBeginTime(startTime);
                dto.setEndTime(endTime);
            }
            try {
                List<String> betweenDays = DateUtils.getBetweenDays(dto.getBeginTime(), dto.getEndTime());

                if (betweenDays == null) {
                    return HttpResult.error();
                }
                Map<String, Object> userMap = null;
                if (dto.getType() == 1) {
                    List<StatisticsDateVO> userNumDailyV2 = baseMapper.getUserNumDailyV2();
                    userMap = userNumDailyV2.stream().collect(Collectors.toMap(StatisticsDateVO::getDate, StatisticsDateVO::getNum, (key1, key2) -> key2));
                }
                if (dto.getType() == 2) {
                    List<StatisticsDateVO> orderIncomeDailyV2 = baseMapper.getOrderIncomeDailyV2(dto.getUserId());
                    userMap = orderIncomeDailyV2.stream().collect(Collectors.toMap(StatisticsDateVO::getDate, StatisticsDateVO::getNum, (key1, key2) -> key2));
                }
                if (dto.getType() == 3) {
                    List<StatisticsDateVO> orderNumDailyV2 = baseMapper.getOrderNumDailyV2(dto.getUserId());
                    userMap = orderNumDailyV2.stream().collect(Collectors.toMap(StatisticsDateVO::getDate, StatisticsDateVO::getNum, (key1, key2) -> key2));
                }
                for (String day : betweenDays) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("date", day);
                    if (userMap == null) {
                        data.put("num", 0);
                        continue;
                    }
                    // 新增用户折线图
                    if (userMap.get(day) != null) {
                        data.put("num", userMap.get(day));
                    } else {
                        data.put("num", 0);
                    }
                    res.add(data);
                }
                return HttpResult.ok(res);
            } catch (ParseException e) {
                return HttpResult.error("日期解析失败");
            }
        }

        @Override
        public HttpResult<List<Map<String, Object>>> getUserNumDaily (MallUser params){
            List<Map<String, Object>> res = new ArrayList<>();
            Map<String, Object> map = params.getParams();
            try {
                List<String> betweenDays = DateUtils.getBetweenDays(String.valueOf(map.get("beginTime")), String.valueOf(map.get("endTime")));

                if (betweenDays == null) {
                    return HttpResult.error();
                }
                for (String day : betweenDays) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("date", day);
                    data.put("num", baseMapper.getUserNumDaily(day));
                    res.add(data);
                }
                return HttpResult.ok(res);
            } catch (ParseException e) {
                return HttpResult.error("日期解析失败");
            }
        }

        @Override
        public HttpResult<Boolean> delAppOrder (ReqIdParam param){
            MallStoreOrder byId = getById(param.getId());
            if (byId == null) {
                return HttpResult.error("无该订单");
            }
            byId.setAppDel(true);
            updateById(byId);
            return HttpResult.ok();
        }

        /*******
         * 取消订单
         * @param param
         * @return
         */
        @Override
        public HttpResult<Boolean> cancelPayOrder (ReqIdParam param){
            MallStoreOrder mallOrder = getById(param.getId());
            if (mallOrder == null) {
                return HttpResult.error("无该订单");
            }
            List<MallSetmealNorms> goodsNorms = new ArrayList();
            List<MallStoreGoods> goods = new ArrayList();
            List<MallStoreOrderGoods> list = mallStoreOrderGoodsService.lambdaQuery().eq(MallStoreOrderGoods::getOrderSn, mallOrder.getOrderSn()).list();
            for (MallStoreOrderGoods orderGoods : list) {
                //更改订单状态
                orderGoods.setOrderStatus(OrderStatus.DEL_PAY);
                mallStoreOrderGoodsService.updateMallStoreOrderGoods(orderGoods);

                //增加售商品库存（规格）
                MallSetmealNorms mallGoodsNorms = mallSetmealNormsService.lambdaQuery().eq(MallSetmealNorms::getId, orderGoods.getNormsId()).one();
                mallGoodsNorms.setInventory(mallGoodsNorms.getInventory() + orderGoods.getNumber());
                goodsNorms.add(mallGoodsNorms);
                // 增加商品库存
                MallStoreGoods one = mallStoreGoodsService.lambdaQuery().eq(MallStoreGoods::getId, orderGoods.getGoodsId()).one();
                one.setInventory(one.getInventory() + orderGoods.getNumber());
                one.setCommoditySales(one.getCommoditySales() - 1);
            }
            mallOrder.setStatusUser(UserOrderStatus.CANCEL_PAY);
            mallOrder.setOrderStatus(OrderStatus.DEL_PAY);
            updateById(mallOrder);
            mallStoreGoodsService.updateBatchById(goods);
            mallSetmealNormsService.updateBatchById(goodsNorms);

            //优惠券返回
            if (mallOrder.getCouponId() != null) {
                mallCouponUserService.updateState(mallOrder.getId(), mallOrder.getUuid(), AllEnum.couponType.EXISTENCE.getType());
            }
            return HttpResult.ok();
        }

        /****
         * 申请售后
         * @param param
         * @return
         */
        @Override
        public HttpResult<Boolean> afterSaleOrder (ReqIdParam param){
            MallStoreOrderGoods orderGoods = mallStoreOrderGoodsService.getById(param.getId());
            if (orderGoods == null) {
                return HttpResult.error("无该订单");
            }
            orderGoods.setAftersaleStatus(AfterSaleStatus.ALREADY_APPLIED.getValue());
            mallStoreOrderGoodsService.updateById(orderGoods);
            return HttpResult.ok();
        }

        /*****
         * 10分钟未支付 取消订单 后者拼团砍价没成功取消订单
         * @param orderVO
         * @return
         */
        @Lock4j(name = Lock4jConstant.CANCEL_ORDER, keys = "#orderVO.orderSn", acquireTimeout = 30000)
        @Override
        public HttpResult<Boolean> cancelOrder (OrderVO orderVO){
            //未支付取消订单
            MallStoreOrder mallOrder = lambdaQuery().eq(MallStoreOrder::getOrderSn, orderVO.getOrderSn()).one();
            if (mallOrder == null) {
                log.info("没有订单信息为{}", orderVO);
                return HttpResult.ok(true);
            }
            if (mallOrder.getOrderStatus().compareTo(OrderStatus.PAY) == 0) {
                cancelPayOrder(new ReqIdParam(mallOrder.getId()));
            }

            return HttpResult.ok(true);
        }

/*        @Override
        public OrderStatisticsVO supplierOrderStatistics (Long userId){
            return baseMapper.supplierOrderStatistics(userId);
        }*/

        @Override
        public HttpResult<List<Map<String, Object>>> getOrderIncomeDaily (MallStoreOrder params){
            List<Map<String, Object>> res = new ArrayList<>();
            Map<String, Object> map = params.getParams();
            try {
                List<String> betweenDays = DateUtils.getBetweenDays(String.valueOf(map.get("beginTime")), String.valueOf(map.get("endTime")));

                if (betweenDays == null) {
                    return HttpResult.error();
                }
                for (String day : betweenDays) {
                    Map<String, Object> data = new HashMap<>();
                    data.put("date", day);
                    data.put("num", baseMapper.getOrderIncomeDaily(day, params.getUserId()));
                    res.add(data);
                }
                return HttpResult.ok(res);
            } catch (ParseException e) {
                return HttpResult.error("日期解析失败");
            }
        }

        @Override
        public MallStoreOrder getOrderByOrderSn (String orderSn){
            return lambdaQuery().eq(MallStoreOrder::getOrderSn, orderSn).one();
        }

        /****
         *
         * @param orderVO
         * @param minute   分钟
         */
        private void sendDelayMessageCancelOrder (OrderVO orderVO,long minute){
            //砍价没有取消订单
            long delayTimes = minute * 1000 * 60;
            //发送延迟消息
            rabbitUtils.sendMessage(orderVO, delayTimes);
        }


        /**
         * 后台首页饼图统计
         *
         * @return 结果
         * @Author lx
         * @Date: 2022/09/23 11:01
         */
        @Override
        public AdminIndexStaticsVO indexStatistics () {
            AdminIndexStaticsVO adminIndexStaticsVo = new AdminIndexStaticsVO();
       /* // 会员用户数目
        Integer vipCount = mallUserService.lambdaQuery().eq(MallUser::getUserLevel, UserType.INTERMEDIATE_MEMBER).count();*/
            // 普通用户数目
            Integer userCount = mallUserService.lambdaQuery().eq(MallUser::getHeadType, UserType.ORDINARY).count();
            //adminIndexStaticsVo.setVipCount(vipCount != null ? vipCount : 0);
            adminIndexStaticsVo.setUserCount(userCount != null ? userCount : 0);
            // 初始化参数
            adminIndexStaticsVo.setCutAmount(BigDecimal.ZERO);
            adminIndexStaticsVo.setCutCount(0);
            adminIndexStaticsVo.setKillAmount(BigDecimal.ZERO);
            adminIndexStaticsVo.setKillCount(0);
            adminIndexStaticsVo.setShopAmount(BigDecimal.ZERO);
            adminIndexStaticsVo.setShopCount(0);
            adminIndexStaticsVo.setPtAmount(BigDecimal.ZERO);
            adminIndexStaticsVo.setPtCount(0);

            // 统计订单信息
            List<AdminIndexVo> adminIndexVos = baseMapper.queryIndexStatistics();
            if (adminIndexVos != null && adminIndexVos.size() > 0) {
                for (AdminIndexVo vo : adminIndexVos) {
                    if (vo.getOrderType() == OrderType.SHOP) {
                        adminIndexStaticsVo.setShopAmount(vo.getActualPriceTotal() != null ? vo.getActualPriceTotal() : BigDecimal.ZERO);
                        adminIndexStaticsVo.setShopCount(vo.getOrderCount() != null ? vo.getOrderCount() : 0);
                    }
                }
            }

            return adminIndexStaticsVo;
        }

        @Override
        public MallAdminOrderStatisticsVO orderStatistics (Long userId, Integer orderMold){
            LocalDateTime now = LocalDateTime.now();
            MallAdminOrderStatisticsVO vo = new MallAdminOrderStatisticsVO();
            // 根据 type 1|已完成 2|待付款 3|待发货 4|待收货 5|已取消

            // 已完成订单金额
            BigDecimal overMoney = baseMapper.orderStatistics(1, null, userId, orderMold);
            vo.setOverMoney(overMoney);

            // 今日已完成订单金额
            BigDecimal todayOverMoney = baseMapper.orderStatistics(1, now, userId, orderMold);
            vo.setTodayOverMoney(todayOverMoney);

            // 待付款订单金额
            BigDecimal waitPayMoney = baseMapper.orderStatistics(2, null, userId, orderMold);
            vo.setWaitPayMoney(waitPayMoney);

            // 今日待付款订单金额
            BigDecimal todayWaitPayMoney = baseMapper.orderStatistics(2, now, userId, orderMold);
            vo.setTodayWaitPayMoney(todayWaitPayMoney);

            // 待发货订单金额
            BigDecimal waitDeliverMoney = baseMapper.orderStatistics(3, null, userId, orderMold);
            vo.setWaitDeliverMoney(waitDeliverMoney);

            // 今日待发货订单金额
            BigDecimal todayWaitDeliverMoney = baseMapper.orderStatistics(3, now, userId, orderMold);
            vo.setTodayWaitDeliverMoney(todayWaitDeliverMoney);

            // 待收货订单金额
            BigDecimal waitReceiveMoney = baseMapper.orderStatistics(4, null, userId, orderMold);
            vo.setWaitReceiveMoney(waitReceiveMoney);

            // 今日待收货订单金额
            BigDecimal todayWaitReceiveMoney = baseMapper.orderStatistics(4, now, userId, orderMold);
            vo.setTodayWaitReceiveMoney(todayWaitReceiveMoney);

            // 已取消订单金额
            BigDecimal cancelMoney = baseMapper.orderStatistics(5, null, userId, orderMold);
            vo.setCancelMoney(cancelMoney);

            // 今日已取消订单金额
            BigDecimal todayCancelMoney = baseMapper.orderStatistics(5, now, userId, orderMold);
            vo.setTodayCancelMoney(todayCancelMoney);

            if (orderMold != null && orderMold == 4) {
                // 会员订单总金额
                BigDecimal memberMoney = baseMapper.memberStatistics(null, null);
                vo.setMemberMoney(memberMoney);

                // 今日会员订单总金额
                BigDecimal todayMemberMoney = baseMapper.memberStatistics(null, now);
                vo.setTodayMemberMoney(todayMemberMoney);
            }

            return vo;
        }

        @Override
        public MallAdminMemberStatisticsVO memberStatistics () {
            MallAdminMemberStatisticsVO vo = new MallAdminMemberStatisticsVO();
            LocalDateTime now = LocalDateTime.now();
            // 微信支付总金额
            BigDecimal wxPayMoney = baseMapper.memberStatistics(PayType.WX_PAY.getValue(), null);
            vo.setWxPayMoney(wxPayMoney);

            // 今日微信支付总金额
            BigDecimal todayWxPayMoney = baseMapper.memberStatistics(PayType.WX_PAY.getValue(), now);
            vo.setTodayWxPayMoney(todayWxPayMoney);

            // 支付宝支付总金额
            BigDecimal AliPayMoney = baseMapper.memberStatistics(PayType.ALI_PAY.getValue(), null);
            vo.setAliPayMoney(AliPayMoney);

            // 今日支付宝支付总金额
            BigDecimal todayAliPayMoney = baseMapper.memberStatistics(PayType.ALI_PAY.getValue(), now);
            vo.setTodayAliPayMoney(todayAliPayMoney);

            // 余额支付总金额
            BigDecimal balancePayMoney = baseMapper.memberStatistics(PayType.CR_PAY.getValue(), null);
            vo.setBalancePayMoney(balancePayMoney);

            // 今日余额支付总金额
            BigDecimal todayBalancePayMoney = baseMapper.memberStatistics(PayType.CR_PAY.getValue(), now);
            vo.setTodayBalancePayMoney(todayBalancePayMoney);
            return vo;
        }

    @Override
    public OrderStatisticsVO supplierOrderStatistics(Long userId) {
        return baseMapper.storeOrderStatistics(userId);
    }

    @Override
        public HttpResult<ResOrderCountVO> orderCount(LoginUser loginUser){
            ResOrderCountVO resOrderCount = baseMapper.selectOrderCount(loginUser.getAccountLogin().getUuid());

            return HttpResult.ok(resOrderCount);
        }
    @Override
    public Integer buyers(Long goodsId) {
        return baseMapper.buyers(goodsId);
    }

    }

